import pandas as pd
import random
from pyecharts import options as opts
from pyecharts.charts import HeatMap, Page, Line
from pyecharts.components import Table
from bs4 import BeautifulSoup



def create_heatmap(result_df, label, x_name, y_name):
    pivot_df = result_df.pivot_table(
        values=f'{label}',
        index=f'{y_name}',  # Y轴作为行
        columns=f'{x_name}',  # X轴作为列
        aggfunc='mean'  # 处理重复值：取平均值
    )
    rows = len(pivot_df)
    cols = len(pivot_df.columns)
    datas = []
    for i in range(rows):
        for j in range(cols):
            datas.append([j, i , pivot_df.iloc[i, j]])
    if label == "max_drawdown":
        range_color = ["#00FF00", "#FFFF00", "#FF0000"][::-1]  # 绿-黄-红
    else:
        range_color = ["#00FF00", "#FFFF00", "#FF0000"]  # 绿-黄-红
    # 绘制热力图
    heatmap = (
        HeatMap()
        .add_xaxis(pivot_df.columns.tolist())
        .add_yaxis(
            f"{label}",
            pivot_df.index.tolist(),
            datas,
            label_opts=opts.LabelOpts(is_show=False),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title=f"{label}热力图"),
            visualmap_opts=opts.VisualMapOpts(
                min_=result_df[f"{label}"].min(),
                max_=result_df[f"{label}"].max(),
                is_calculable=True,
                range_color=range_color,
            ),
            tooltip_opts=opts.TooltipOpts(
                trigger="item",
                axis_pointer_type="cross"
            ),
        )
    )
    return heatmap


def create_data_table(df, title):
    """创建数据表格"""
    # 转换数据为表格格式
    headers = df.columns.tolist()
    rows = []
    for _, row in df.iterrows():
        rows.append([str(x) for x in row.tolist()])

    table = (
        Table()
        .add(headers, rows)
        .set_global_opts(
            title_opts=opts.ComponentTitleOpts(title=title, subtitle="")
        )
    )
    return table


def create_line_chart(df, title, x_label, y_label1, y_label2, m, n, x_name, y_name):
    """创建折线图"""
    line = (
        Line()
        .add_xaxis(df[x_label].tolist())
        .add_yaxis(f"{x_name}={m},{y_name}={n}", df[y_label1].tolist(),
                  is_smooth=True,
                  label_opts=opts.LabelOpts(is_show=False))
        .add_yaxis("hold_btc", df[y_label2].tolist(),
                  is_smooth=True,
                  label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            tooltip_opts=opts.TooltipOpts(trigger="axis"),
            yaxis_opts=opts.AxisOpts(
                axislabel_opts=opts.LabelOpts(formatter="{value}")
            )
        )
    )
    return line


def gen_html(frequency, begin_date, x_name, y_name):
    path = f"{frequency}/{begin_date}/result/backtest_result_heatmap.csv"
    result_df = pd.read_csv(path)
    page = Page(layout=Page.SimplePageLayout)
    for label in ["annualized_return", "annualized_volatility", "annualized_shape", "turnover", "margin",
                         "fitness", "excess_return", "relative_return", "max_drawdown", "information_ratio",
                         "calmar_ratio", "yearly_count", "winning_rate", "profit_loss_ratio", "kelly_fraction"]:
        heatmap = create_heatmap(result_df, label, x_name, y_name)
        page.add(heatmap)
    for table_name in ["annualized_shape", "margin", "calmar_ratio", "information_ratio"]:
        path = f"{frequency}/{begin_date}/top3/{table_name}.csv"
        table_df = pd.read_csv(path)
        table = create_data_table(table_df, f"{table_name}_top3")
        page.add(table)

        for _, row in table_df.iterrows():
            m = int(row[f'{x_name}'])
            n = int(row[f'{y_name}'])

            path = f"{frequency}/{begin_date}/nav/nav_{m}_{n}.csv"
            nav_df = pd.read_csv(path)
            line = create_line_chart(nav_df, "净值曲线", "date", f"nav", "nav(hold_btc)", m, n,
                                     x_name, y_name)
            page.add(line)

    # 生成并保存
    html_path = f"{frequency}/{begin_date}/{frequency}_{begin_date}.html"
    page.render(html_path)
    with open(html_path, 'r', encoding='utf-8') as f:
        html_content = f.read()

    # 使用BeautifulSoup解析
    soup = BeautifulSoup(html_content, 'html.parser')

    # 1. 为表格容器添加样式
    chart_containers = soup.find_all(class_='chart-container')
    for container in chart_containers:
        if container.has_attr('style'):
            container['style'] += 'overflow-x: auto;'
        else:
            container['style'] = 'overflow-x: auto;'
    # 保存修改后的HTML
    with open(html_path, 'w', encoding='utf-8') as file:
        file.write(str(soup))